package com.danceforyou.medium.service.impl;

import com.danceforyou.common.restful.exception.BizException;
import com.danceforyou.common.restful.exception.BizExceptionEnum;
import com.danceforyou.common.service.OperationService;
import com.danceforyou.common.service.impl.BaseServiceImpl;
import com.danceforyou.common.util.AssertUtil;
import com.danceforyou.common.util.Constants;
import com.danceforyou.common.vo.SqlOrderEnum;
import com.danceforyou.medium.dao.MediumDAO;
import com.danceforyou.medium.model.MediumDO;
import com.danceforyou.medium.model.MediumLabelDO;
import com.danceforyou.medium.service.MediumLabelService;
import com.danceforyou.medium.service.MediumService;
import com.danceforyou.medium.vo.MediumVO;
import com.danceforyou.user.model.UserDO;
import com.danceforyou.user.service.UserService;
import com.danceforyou.user.vo.UserVO;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;

/**
* 类名称：MediumServiceImpl
* 创建人：danceforyou
* 创建时间：2021年02月02日
* 版本号：1.0v
*/
@Service("mediumService")
public class MediumServiceImpl extends BaseServiceImpl<Long, MediumDO, MediumVO, MediumDAO> implements MediumService {
    @Autowired
    private MediumDAO mediumDAO;
    @Autowired
    private OperationService operationService;
    @Autowired
    private UserService userService;
    @Autowired
    private MediumLabelService mediumLabelService;
    @Autowired(required = false)
    private HttpSession session;

    @Override
    public MediumDAO getDao() {
        return mediumDAO;
    }

    @Override
    public void saveInfo(MediumDO medium) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        medium.setName(medium.getName().trim());
        medium.setWeChatNo(medium.getWeChatNo().trim());
        //不能重复录入相同的媒体
        if (medium.getType() == 1) {
            MediumDO temp = this.getByCondition(new HashMap<String, Object>() {{
                put("type", 1);
                put("isDelete", 0);
                put("weChatNo", medium.getWeChatNo());
            }});
            AssertUtil.isNull(temp, "该公众号ID已存在，请勿重复录入");
        } else if (medium.getType() == 2) {
            MediumDO temp = this.getByCondition(new HashMap<String, Object>() {{
                put("type", 2);
                put("isDelete", 0);
                put("name", medium.getName());
            }});
            AssertUtil.isNull(temp, "该视频号名称已存在，请勿重复录入");
        }
        //保存公众号
        medium.setCreateUserId(loginUser.getId());
        medium.setCreateDate(new Date());
        medium.setUpdateDate(new Date());
        medium.setStatus(Constants.MEDIUM_STATUS_ENABLE);
        medium.setIsDelete(false);
        this.insert(medium);
        operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_ADD, loginUser, null);
    }

    @Override
    public void updateInfo(MediumDO medium) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        medium.setName(medium.getName().trim());
        medium.setWeChatNo(medium.getWeChatNo().trim());
        MediumDO temp = this.getById(medium.getId());
        AssertUtil.notNull(temp, "信息不存在");
        if (!loginUser.getRole().getRoleType().equals(Constants.ROLE_GLB_CODE)) {
            AssertUtil.isTrue(temp.getCreateUserId().equals(loginUser.getId()), "非法操作");
        }
        //不能重复录入相同的媒体
        if (medium.getType() == 1 && !temp.getWeChatNo().equals(medium.getWeChatNo())) {
            MediumDO tempMedium = this.getByCondition(new HashMap<String, Object>() {{
                put("type", 1);
                put("isDelete", 0);
                put("weChatNo", medium.getWeChatNo());
            }});
            AssertUtil.isNull(tempMedium, "该公众号ID已存在，请勿重复录入");
        } else if (medium.getType() == 2 && !temp.getName().equals(medium.getName())) {
            MediumDO tempMedium = this.getByCondition(new HashMap<String, Object>() {{
                put("type", 2);
                put("isDelete", 0);
                put("name", medium.getName());
            }});
            AssertUtil.isNull(tempMedium, "该视频号名称已存在，请勿重复录入");
        }
        medium.setUpdateDate(new Date());
        this.update(medium);
        operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_EDIT, loginUser, null);
    }

    @Override
    public int deleteInfoByIds(String ids) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String[] idArr = ids.split(",");
        int i = 0;
        for (String id : idArr) {
            MediumDO medium = this.getById(Long.valueOf(id));
            AssertUtil.notNull(medium, "信息不存在");
            if (!loginUser.getRole().getRoleType().equals(Constants.ROLE_GLB_CODE)) {
                AssertUtil.isTrue(medium.getCreateUserId().equals(loginUser.getId()), "非法操作");
            }
            i += this.setDeleteById(medium.getId());
            operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_DELETE, loginUser, null);
        }
        return i;
    }

    @Override
    public int saveDelegateMediumInfo(String mediumIds, Long mediumUserId) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        UserDO mediumUser = userService.getById(mediumUserId);
        AssertUtil.notNull(mediumUser, "员工信息不存在");
        String[] mediumIdArr = mediumIds.split(",");
        int i = 0;
        for (String mediumId : mediumIdArr) {
            MediumDO medium = this.getById(Long.valueOf(mediumId));
            AssertUtil.notNull(medium, "信息不存在");
            if (!loginUser.getRole().getRoleType().equals(Constants.ROLE_GLB_CODE)) {
                AssertUtil.isTrue(medium.getCreateUserId().equals(loginUser.getId()), "非法操作");
            }
            medium.setCreateUserId(mediumUserId);
            i += this.update(medium);
            operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_DELEGATE, loginUser, "目标员工："+ mediumUser.getName());
        }
        return i;
    }

    @Override
    public int saveUploadMediumInfos(MultipartFile file) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        int rowIndex = 2;// 从哪一行开始处理数据
        int cellIndex = 0;//从哪一列开始处理数据
        try {
            int result = 0;
            Workbook book;
            try {
                // Excel 2007获取方法
                book = new XSSFWorkbook(file.getInputStream());
            } catch (Exception ex) {
                // Excel 2003获取方法
                book = new HSSFWorkbook(file.getInputStream());
            }
            // 读取表格的第一个工作簿
            Sheet sheet = book.getSheetAt(0);
            int totalRows = sheet.getLastRowNum();
            // 定义 row、cell
            Row row;
            // 遍历所有行
            forRow : for (; rowIndex <= totalRows; rowIndex++) {
                row = sheet.getRow(rowIndex);
                if (row == null) {
                    continue;
                }
                // 遍历所有列，保存公众号信息
                MediumDO medium = new MediumDO();
                medium.setType(1);
                medium.setCreateUserId(loginUser.getId());
                medium.setCreateDate(new Date());
                medium.setUpdateDate(new Date());
                medium.setStatus(Constants.MEDIUM_STATUS_ENABLE);
                medium.setIsDelete(false);
                //不能重复录入相同的公众号
                int totalCells = row.getLastCellNum();
                for (cellIndex = 0; cellIndex < totalCells; cellIndex++) {
                    Cell cell = row.getCell(cellIndex);
                    if (cell == null) {
                        continue;
                    }
                    switch (cellIndex) {
                        case 0:
                            //公众号类别
                            medium.setLabel(cell.toString().trim());
                            AssertUtil.isTrue(medium.getLabel().length() >= 1 && medium.getLabel().length() <= 20, "公众号类别长度在1-20之间");
                            MediumLabelDO mediumLabel = mediumLabelService.getByProperty("labelName", medium.getLabel(), "type", SqlOrderEnum.ASC);
                            if (mediumLabel == null || mediumLabel.getType() == 2) {
                                mediumLabel = new MediumLabelDO();
                                mediumLabel.setType(1);
                                mediumLabel.setLabelName(medium.getLabel());
                                mediumLabelService.insert(mediumLabel);
                            }
                            break;
                        case 1:
                            //公众号名称
                            medium.setName(cell.toString().trim());
                            AssertUtil.isTrue(medium.getName().length() >= 1 && medium.getName().length() <= 100, "公众号名称长度在1-100之间");
                            break;
                        case 2:
                            //微信号
                            medium.setWeChatNo(cell.toString().trim());
                            AssertUtil.isTrue(medium.getWeChatNo().length() >= 1 && medium.getWeChatNo().length() <= 20, "微信号长度在1-20之间");
                            MediumDO temp = this.getByProperty("weChatNo", medium.getWeChatNo(), "isDelete", SqlOrderEnum.ASC);
                            if (temp != null && !temp.getIsDelete()) {
                                continue forRow;
                            }
                            break;
                        case 3:
                            //粉丝数量（万）
                            medium.setFansSheets(new BigDecimal(cell.toString().trim()));
                            break;
                        case 4:
                            //粉丝年龄段
                            medium.setFansAge(cell.toString().trim());
                            AssertUtil.isTrue(medium.getFansAge().length() >= 1 && medium.getFansAge().length() <= 10, "粉丝年龄段长度在1-10之间");
                            break;
                        case 5:
                            //男粉比例
                            medium.setManRatio(new BigDecimal(cell.toString().trim()));
                            break;
                        case 6:
                            //头条执行价
                            medium.setHeadLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 7:
                            //次条执行价
                            medium.setSecondLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 8:
                            //三条执行价
                            medium.setThirdLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 9:
                            //尾条执行价
                            medium.setTailLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 10:
                            //头条成本价
                            medium.setHeadLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 11:
                            //次条成本价
                            medium.setSecondLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 12:
                            //三条成本价
                            medium.setThirdLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 13:
                            //尾条成本价
                            medium.setTailLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 14:
                            //发票税点
                            String bill_point = cell.toString().trim();
                            switch (bill_point) {
                                case "不含票":
                                    medium.setBillPoint(0);
                                    break;
                                case "普票1%":
                                    medium.setBillPoint(-1);
                                    break;
                                case "普票3%":
                                    medium.setBillPoint(-3);
                                    break;
                                case "普票6%":
                                    medium.setBillPoint(-6);
                                    break;
                                case "专票1%":
                                    medium.setBillPoint(1);
                                    break;
                                case "专票3%":
                                    medium.setBillPoint(3);
                                    break;
                                case "专票6%":
                                    medium.setBillPoint(6);
                                    break;
                            }
                            break;
                        case 15:
                            //拒接广告类型
                            medium.setRefuseType(cell.toString().trim());
                            AssertUtil.isTrue(medium.getRefuseType().length() <= 200, "拒接广告类型长度在1-200之间");
                            break;
                        case 16:
                            //刷号类型
                            medium.setBrushType(cell.toString().trim());
                            AssertUtil.isTrue(medium.getBrushType().length() <= 10, "刷号类型长度在1-10之间");
                            break;
                        case 17:
                            //公司主体
                            medium.setHostCompany(cell.toString().trim());
                            AssertUtil.isTrue(medium.getHostCompany().length() <= 100, "公司主体长度在1-100之间");
                            break;
                        case 18:
                            //联系方式
                            medium.setHostContact(cell.toString().trim());
                            AssertUtil.isTrue(medium.getHostContact().length() <= 100, "其他联系方式长度在1-100之间");
                            break;
                        default:
                    }
                }
                result += this.insert(medium);
                operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_ADD, loginUser, "批量导入");
            }
            return result;
        } catch (Exception e) {
            if (e instanceof BizException) {
                throw new BizException(((BizException) e).getMsg() + "，在第"+ (rowIndex + 1) +"行第"+ (cellIndex + 1) +"列");
            } else {
                e.printStackTrace();
                throw new BizException("解析文件失败，在第"+ (rowIndex + 1) +"行第"+ (cellIndex + 1) +"列");
            }
        }
    }

    @Override
    public int saveUploadMediumVideoInfos(MultipartFile file) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        int rowIndex = 2;// 从哪一行开始处理数据
        int cellIndex = 0;//从哪一列开始处理数据
        try {
            int result = 0;
            Workbook book;
            try {
                // Excel 2007获取方法
                book = new XSSFWorkbook(file.getInputStream());
            } catch (Exception ex) {
                // Excel 2003获取方法
                book = new HSSFWorkbook(file.getInputStream());
            }
            // 读取表格的第一个工作簿
            Sheet sheet = book.getSheetAt(0);
            int totalRows = sheet.getLastRowNum();
            // 定义 row、cell
            Row row;
            // 遍历所有行
            forRow : for (; rowIndex <= totalRows; rowIndex++) {
                row = sheet.getRow(rowIndex);
                if (row == null) {
                    continue;
                }
                // 遍历所有列，保存视频号信息
                MediumDO medium = new MediumDO();
                medium.setType(2);
                medium.setCreateUserId(loginUser.getId());
                medium.setCreateDate(new Date());
                medium.setUpdateDate(new Date());
                medium.setStatus(Constants.MEDIUM_STATUS_ENABLE);
                medium.setIsDelete(false);
                //不能重复录入相同的视频号
                int totalCells = row.getLastCellNum();
                for (cellIndex = 0; cellIndex < totalCells; cellIndex++) {
                    Cell cell = row.getCell(cellIndex);
                    if (cell == null) {
                        continue;
                    }
                    switch (cellIndex) {
                        case 0:
                            //视频号类别
                            medium.setLabel(cell.toString().trim());
                            AssertUtil.isTrue(medium.getLabel().length() >= 1 && medium.getLabel().length() <= 20, "视频号类别长度在1-20之间");
                            MediumLabelDO mediumLabel = mediumLabelService.getByProperty("labelName", medium.getLabel(), "type", SqlOrderEnum.DESC);
                            if (mediumLabel == null || mediumLabel.getType() == 1) {
                                mediumLabel = new MediumLabelDO();
                                mediumLabel.setType(2);
                                mediumLabel.setLabelName(medium.getLabel());
                                mediumLabelService.insert(mediumLabel);
                            }
                            break;
                        case 1:
                            //视频号名称
                            medium.setName(cell.toString().trim());
                            AssertUtil.isTrue(medium.getName().length() >= 1 && medium.getName().length() <= 100, "视频号名称长度在1-100之间");
                            MediumDO temp = this.getByCondition(new HashMap<String, Object>() {{
                                put("type", 2);
                                put("isDelete", 0);
                                put("name", medium.getName());
                            }});
                            if (temp != null) {
                                continue forRow;
                            }
                            break;
                        case 2:
                            //粉丝数量（万）
                            medium.setFansSheets(new BigDecimal(cell.toString().trim()));
                            break;
                        case 3:
                            //粉丝年龄段
                            medium.setFansAge(cell.toString().trim());
                            AssertUtil.isTrue(medium.getFansAge().length() >= 1 && medium.getFansAge().length() <= 10, "粉丝年龄段长度在1-10之间");
                            break;
                        case 4:
                            //男粉比例
                            medium.setManRatio(new BigDecimal(cell.toString().trim()));
                            break;
                        case 5:
                            //头条执行价
                            medium.setHeadLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 6:
                            //次条执行价
                            medium.setSecondLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 7:
                            //三条执行价
                            medium.setThirdLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 8:
                            //尾条执行价
                            medium.setTailLineQuoted(new BigDecimal(cell.toString().trim()));
                            break;
                        case 9:
                            //头条成本价
                            medium.setHeadLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 10:
                            //次条成本价
                            medium.setSecondLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 11:
                            //三条成本价
                            medium.setThirdLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 12:
                            //尾条成本价
                            medium.setTailLineCost(new BigDecimal(cell.toString().trim()));
                            break;
                        case 13:
                            //发票税点
                            String bill_point = cell.toString().trim();
                            switch (bill_point) {
                                case "不含票":
                                    medium.setBillPoint(0);
                                    break;
                                case "普票1%":
                                    medium.setBillPoint(-1);
                                    break;
                                case "普票3%":
                                    medium.setBillPoint(-3);
                                    break;
                                case "普票6%":
                                    medium.setBillPoint(-6);
                                    break;
                                case "专票1%":
                                    medium.setBillPoint(1);
                                    break;
                                case "专票3%":
                                    medium.setBillPoint(3);
                                    break;
                                case "专票6%":
                                    medium.setBillPoint(6);
                                    break;
                            }
                            break;
                        case 14:
                            //拒接广告类型
                            medium.setRefuseType(cell.toString().trim());
                            AssertUtil.isTrue(medium.getRefuseType().length() <= 200, "拒接广告类型长度在1-200之间");
                            break;
                        case 15:
                            //公司主体
                            medium.setHostCompany(cell.toString().trim());
                            AssertUtil.isTrue(medium.getHostCompany().length() <= 100, "公司主体长度在1-100之间");
                            break;
                        case 16:
                            //联系方式
                            medium.setHostContact(cell.toString().trim());
                            AssertUtil.isTrue(medium.getHostContact().length() <= 100, "联系方式长度在1-100之间");
                            break;
                        default:
                    }
                }
                result += this.insert(medium);
                operationService.saveOperation(Constants.OPER_TABLE_MEDIUM, medium.getId(), Constants.OPER_ADD, loginUser, "批量导入");
            }
            return result;
        } catch (Exception e) {
            if (e instanceof BizException) {
                throw new BizException(((BizException) e).getMsg() + "，在第"+ (rowIndex + 1) +"行第"+ (cellIndex + 1) +"列");
            } else {
                e.printStackTrace();
                throw new BizException("解析文件失败，在第"+ (rowIndex + 1) +"行第"+ (cellIndex + 1) +"列");
            }
        }
    }
}
